package pa165.dominatingspecies.rest;

import java.net.URI;

import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.springframework.dao.DataAccessException;
import org.springframework.security.access.prepost.PreAuthorize;

import pa165.dominating.species.service.EnvironmentService;
import pa165.dominating.species.tos.EnvironmentTo;

/**
 *
 * @author Stanislau Dubrouski
 */
@Path("/environments")
public class EnvironmentRestService {

    private EnvironmentService envService;

    @Context
    private UriInfo context;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('WORKER')")
    public Response getAllEnvironments() {
        List<EnvironmentTo> found = envService.getAllEnvironments();
        GenericEntity<List<EnvironmentTo>> all = new GenericEntity<List<EnvironmentTo>>(found) {
        };
        return Response.ok(all).build();
    }

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('WORKER')")
    public EnvironmentTo getEnvironmentById(@PathParam("id") Long id) {
        return envService.getEnvironmentById(id);
    }

    @POST
    @Path("create")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('ADMIN')")
    public Response createEnvironment(EnvironmentTo to) {
        boolean thrown = false;
        String msg = null;
        try {
            envService.createEnvironment(to);
        } catch (DataAccessException ex) {
            thrown = true;
            msg = ex.getMessage();
        }
        if (thrown) {
            System.out.println(msg);
            return Response.status(404).entity(msg).build();
        } else {
            List<EnvironmentTo> found = envService.getAllEnvironments();
            Long key = envService.getEnvironmentById(found.get(found.size() - 1).getId()).getId();
            return Response.created(URI.create(context.getAbsolutePath() + "/" + key)).build();
        }
    }
    
    @DELETE
    @Path("delete/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public Response deleteEnvironment(@PathParam("id") Long id){
      boolean thrown = false;
      try{
        envService.deleteEnvironment(envService.getEnvironmentById(id));
      }
      catch(DataAccessException ex){
        thrown = true;
      }
      if(thrown){
        return Response.status(404).entity("Environment with id '" + id +"' cannot be deleted.").build();
      }
      else{
        return Response.status(200).entity("Environment with id '" + id +"' was successfuly deleted.").build();
      }      
    }
    
    @PUT
    @Path("update")
    @Consumes(MediaType.APPLICATION_JSON) 
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('WORKER')")
    public Response updateElement(EnvironmentTo to){
      EnvironmentTo found = envService.getEnvironmentById(to.getId());
      found.setDescription(to.getDescription());
      found.setName(to.getName());
      
      boolean thrown = false;
      try{
       envService.updateEnvironment(found);
      }
      catch(DataAccessException ex){
        thrown = true;
      }
      if(!thrown){
        return Response.ok(envService.getEnvironmentById(found.getId())).build();
      }
      else{
        return Response.status(404).entity("Environment could not be created.").build();
      }      
    }
    
    public void setEnvService(EnvironmentService envService) {
        this.envService = envService;
    }
}
